﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.UI;
using PessMvc.Models;
using PessModel;
using System.Text.RegularExpressions;
using System.Web.Mvc.Html;
using System.Web.Security;
using System.Web.Profile;

namespace PessMvc.Helpers
{
    public static class Extensions
    {
        public static decimal GetExpertScore(this Archive archive)
        {
            string userName = Membership.GetUser().UserName.ToLower();
            decimal score = 0;
            if(!Roles.IsUserInRole(userName, "ExpertJudge"))
            {
                return score;
            }
            using (PESSEntities db = new PESSEntities())
            {
                var expertScore = (from s in db.Scores
                         where s.ArchiveID == archive.ID && s.ExpertJudgeSerialNumber.ToLower() == userName
                         select s).FirstOrDefault();
                if(expertScore != null)
                {
                    score =(decimal)expertScore.Value;
                }
            }
            return score;
        }
        public static IEnumerable<County> GetCounties(this Activity activity)//int activityID)
        {
            IEnumerable<County> counties;
            using (PESSEntities db = new PESSEntities())
            {
                counties = (from s in db.Activities.Find(activity.ID).Subjects
                            join q in db.CandidateQuotas on s.ID equals q.SubjectID
                            select q.County).Distinct().OrderBy(c => c.Code);
                MembershipUser user = Membership.GetUser();
                if (Roles.IsUserInRole(user.UserName, "CountyAdmin"))
                {
                    ProfileBase profile = ProfileBase.Create(user.UserName);
                    string countyCode = (string)profile["CountyCode"];
                    counties = counties.Where(c => c.Code == countyCode);
                }
                else if (Roles.IsUserInRole(user.UserName, "Admin"))
                {
                    //counties = db.Counties;
                }
                else if (Roles.IsUserInRole(user.UserName, "Author"))
                {
                    //counties = db.Counties;
                }
                counties=counties.ToList();
            }
            return counties;
        }
        public static string PrefixZero(this int x)
        {
            if(x>=0&&x<10)
            {
                return string.Format("0{0}", x);
            }
            return x.ToString();
        }
        public static string FileExtName(this string fileName)
        {
            int lastIdx=fileName.LastIndexOf('.');
            return fileName.Substring(lastIdx+1, fileName.Length - lastIdx-1);
        }
        public static MvcHtmlString MenuLink(this HtmlHelper htmlHelper,
                                            string linkText, string actionName, string controllerName,object routeValues)
        {

            string currentAction = htmlHelper.ViewContext.RouteData.GetRequiredString("action");
            string currentController = htmlHelper.ViewContext.RouteData.GetRequiredString("controller");

            if (controllerName == currentController||                
                currentController.RelatedControllers().Contains(controllerName))
            {
                return htmlHelper.ActionLink(linkText, actionName, controllerName, routeValues, new { @class = "selected" });
            }

            return htmlHelper.ActionLink(linkText, actionName, controllerName,routeValues,null);


        }
        private static List<string> RelatedControllers(this string currentController)
        {
            List<string> controllers=new List<string>();
            switch (currentController)
            {
                case "ExpertGroup": case "ExpertJudge":
                    controllers=new List<string> { "ExpertGroup", "ExpertJudge" };
                    break;
                case "Rule":case "Subject":
                    controllers = new List<string> { "Rule", "Subject" };
                    break;
            }
            return controllers;

        }
        public static MvcHtmlString PivotTable(this HtmlHelper helper, DataTable datatable, string xAxisField, string yAxisField, string[] zAxisFields)
        {
            Pivot pivot = new Pivot(datatable);

            StringBuilder sb = new StringBuilder();
            StringWriter sw = new StringWriter(sb);
            HtmlTextWriter htw = new HtmlTextWriter(sw);
            pivot.PivotTable(xAxisField, yAxisField, zAxisFields).RenderControl(htw);
            return MvcHtmlString.Create(sb.ToString());
        }
        //public static MvcHtmlString RichTextareaFor(this HtmlHelper helper, string id, string text = "")
        //{
        //    //return new MvcHtmlString(String.Format(@"<textarea id="{0}" class="tinymce">{1}</textarea>",id,text));
        //    return new MvcHtmlString(String.Format(@"<textarea id=""{0}"" class=""tinymce"">{1}</textarea>", id, text));
        //}
        public static MvcHtmlString ScoreInputControl(this HtmlHelper helper,string name,int limit,decimal value,object htmlatt=null)
        {
            List<SelectListItem> items =( from i in Enumerable.Range(0, limit+1)
                        select new SelectListItem() { Text=i.ToString(), Value = i.ToString() }).ToList();
            //items.Where(it => it.Value == ((int)value).ToString()).FirstOrDefault().Selected = true;
            items.ElementAt((int)value).Selected = true;
            return helper.DropDownList(name, items, htmlatt);
        }

        public static MvcHtmlString GradeInputControl(this HtmlHelper helper, string name, IEnumerable<GradeRule> gradeRules, Grade expertGrade, object htmlatt=null)
        {
            List<SelectListItem> items = (from g in gradeRules
                                          select new SelectListItem() { Text = g.Name, Value = g.ID.ToString() }).ToList();
            if (expertGrade != null)
            {
                //int selectedGradeID = gradeRules.Where(g => g.Name ==expertGrade.GradeRule.Name).FirstOrDefault().ID;
                //items.ElementAt(selectedGradeID).Selected = true;
                for(int i=0;i<items.Count;i++)
                {
                    if(Convert.ToInt32(items[i].Value)==expertGrade.GradeRuleID)
                    {
                        items[i].Selected = true;
                        break;
                    }
                }
            }
            return helper.DropDownList(name, items, htmlatt);
        }
        public static bool CheckVisibility(this HtmlHelper helper, IEnumerable<ArchiveDisplayName> displayNames, string propertyName)
        {
            int count = 0;
            if (displayNames != null)
            {
                count = displayNames.Where(d => d.PropertyName == propertyName && d.Visibility == 1).Count();
            }
            if (count == 1) { return true; }
            else
            {
                return false;
            }
        }
        public static List<ExpertJudgeModel> ToExpertJudgeModelList(this IList<ExpertJudge> experts,int activityID=-1)
        {
            var expertModels = new List<ExpertJudgeModel>();
            foreach (var e in experts)
            {
                var model = e.ToExpertJudgeModel();
                foreach (var group in e.ExpertGroups)
                {
                    if (activityID!=-1&&group.ActivityID == activityID)
                    {
                        model.ExpertGroupCallsign += group.Callsign + " ";
                    }
                }
                expertModels.Add(model);
            }
            return expertModels;
        }
        public static ExpertJudgeModel ToExpertJudgeModel(this ExpertJudge expert)
        {

            var model = new ExpertJudgeModel
            {
                RealName = expert.RealName ?? "",
                Birthdate = expert.BirthDate ?? "1900-1-1",
                Gender = expert.Gender ?? false,
                Phone = expert.Phone ?? "",
                SerialNumber = expert.SerialNumber ?? "",
                ExpertGroupID = expert.ExpertGroupID ?? -1,
                Email = expert.Email ?? "",
                ContactAddress = expert.ContactAddress ?? "",
                ZipCode = expert.ZipCode ?? "",
                SSID=expert.SSID ?? ""
                //ExpertGroupCallsign=e.ExpertGroups.SelectMany(e.ExpertGroups)
                //ExpertGroupCallsign = e.ExpertGroup.Callsign 
            };
            return model;
        }
        public static Author ConvertToAuthor(this AuthorModel model)
        {
            Author author = new Author()
            {
                ContactAddress = model.ContactAddress,
                //Email = model.Email,                
                Phone = model.Phone,
                RealName = model.RealName,
                SerialNumber = model.SerialNumber,
                ZipCode = model.ZipCode
            };
            return author;
        }
        public static AuthorModel ConvertToAuthorModel(this Author author)
        {
            AuthorModel model = new AuthorModel()
            {
                ContactAddress = author.ContactAddress,
                //Email = model.Email,                
                Phone = author.Phone,
                RealName = author.RealName,
                SerialNumber = author.SerialNumber,
                ZipCode = author.ZipCode
            };
            return model;
        }
        public static IHtmlString PhotoImage(this HtmlHelper htmlHelper, string url)
        {
            var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext);
            var img = new TagBuilder("img");
            img.Attributes["alt"] = "[IMAGE]";
            img.Attributes["src"] = urlHelper.Content(url);
            return MvcHtmlString.Create(img.ToString(TagRenderMode.SelfClosing));
        }

        public static string ToLocalName(this ActivityStatus status)
        {
            string value="";
            switch (status)
            {
                case ActivityStatus.Open:
                    value = PessResources.ActivityStatus.Open;
                    break;
                case ActivityStatus.Close:
                    value = PessResources.ActivityStatus.Close;
                    break;
                case ActivityStatus.Done:
                    value = PessResources.ActivityStatus.Done;
                    break;
            }
            return value;
        }

        public static string StripHtmlTags(this string post)
        {
            if (post == null)
            {
                return "";
            }
            else
            {
                return Regex.Replace(post, @"<[^>]*>", String.Empty);
            }
        }
        public static string Truncate(this string input, int length)
        {
            if (input==null||input.Length <= length)
            {
                return input;
            }
            else
            {
                return input.Substring(0, length) + "...";
            }
        }
    }
    public static class PagingHelpers
    {
        ///  <summary>
        /// This method returns an MVCHtmlString which
        /// is used for Paging purpose. this represents
        /// that it is an extension method, PageInfo is a
        /// ViewModel class which I had created and pageUrl
        /// is anomyous type function.
        ///  </summary>
        public static MvcHtmlString PageLinks(this HtmlHelper html, PageInfo pageInfo, Func<int, string> pageUrl)
        {
            //Create an object of StringBuilder class
            StringBuilder result = new StringBuilder();

            for (int i = 1; i <= pageInfo.TotalPages; i++)
            {
                //TagBuilder class is used to create Tag.
                //Here I am creating <a></a> tag.
                TagBuilder tag = new TagBuilder("a");
                //Merge required attributed like href, title etc.
                tag.MergeAttribute("href", pageUrl(i));
                //Set inner heml.
                tag.InnerHtml = i.ToString();

                if (i == pageInfo.CurrentPage)
                {
                    //Add any class if you want to add.
                    tag.AddCssClass("selected");
                }
                //Finally add resulted string in StringBuilder object.
                result.Append(tag.ToString());
            }

            //Create MVCHtmlString.
            return MvcHtmlString.Create(result.ToString());
        }
    }
}